package com.wy2cloud.authorize.security;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;

import com.wy2cloud.authorize.util.HttpServletUtils;
import com.wy2cloud.authorize.util.ProxyPrefixHttpServletRequestWrapper;

/**
 * 自动适配代理前缀的登录授权端点
 * @author admin
 *
 */
public class LoginUrlAuthenticationEntryPointAdapter extends LoginUrlAuthenticationEntryPoint {
	
	private Logger logger=LoggerFactory.getLogger(LoginUrlAuthenticationEntryPointAdapter.class);
	
	public static final String Default_Context_Path="/";
	//Zuul代理头信息的Key
    public static final String Zuul_Forward_Prefix="x-forwarded-prefix";
    
    /**
     * 返回代理前缀
     * @param req HttpServletRequest
     * @param otherProxyPerfix 是否处理其它前缀，是：处理，会处理加上代理传来其它前缀
     * @return
     */
    public static String getZuulPrefix(HttpServletRequest req,Boolean otherProxyPerfix){
        //取zuul下发的proxy-header信息
        String prefixPath=req.getHeader(Zuul_Forward_Prefix);
        if(prefixPath!=null) {
            if(!otherProxyPerfix) return prefixPath;
            String path = req.getServletPath();
            int pos = path.indexOf(prefixPath);
            if (pos > 0) {
                prefixPath = path.substring(0, pos - 1) + prefixPath;
            }
            return prefixPath;
        }
        return null;
    }
    
    private RequestCache requestCache = new HttpSessionRequestCache();
    
	public LoginUrlAuthenticationEntryPointAdapter(String loginFormUrl) {
		super(loginFormUrl);
		// TODO Auto-generated constructor stub
	}
	
	@Override
	protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException exception) {
		// TODO Auto-generated method stub
		//return super.determineUrlToUseForThisRequest(request, response, exception);
		String contextPath=request.getContextPath();
		

        //取zuul下发的proxy-header信息
        String prefixPath= getZuulPrefix(request,false);
        if(prefixPath==null){
            prefixPath="";
        }
        if(!Default_Context_Path.equals(contextPath)){
        	prefixPath+=contextPath;
        }
        if(StringUtils.isNotEmpty(prefixPath)) {
        	return prefixPath+super.determineUrlToUseForThisRequest(request, response, exception);
        }
        return super.determineUrlToUseForThisRequest(request, response, exception);
	}
	
	@Override
	public void commence(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException authException) throws IOException, ServletException {
		// TODO Auto-generated method stub
		super.commence(request, response, authException);
		
		
		
		request = new AmendRequestURIHttpServletRequestWrapper(request);
		
		requestCache.saveRequest(request, response);
		logger.info("RequestURI: {}",request.getRequestURI());
	}

	/**
	 * 修改requestURI路径
	 * @author admin
	 *
	 */
	public static class AmendRequestURIHttpServletRequestWrapper extends HttpServletRequestWrapper {

		private static final String Default_Context_Path="/";
		
		
		public AmendRequestURIHttpServletRequestWrapper(HttpServletRequest request) {
			super(request);
		}
		

		private HttpServletRequest _getHttpServletRequest() {
	        return (HttpServletRequest) super.getRequest();
	    }
		

		
		@Override
		public String getContextPath() {
			String contextPath=_getHttpServletRequest().getContextPath();

	        //取zuul下发的proxy-header信息
	        String prefixPath= HttpServletUtils.getZuulPrefix(_getHttpServletRequest(),false);
	        if(prefixPath == null){
	            prefixPath="";

	        }
	        if(!Default_Context_Path.equals(contextPath)){
	        	contextPath=prefixPath+contextPath;
	        }else {
	        	contextPath=prefixPath;
	        }
	        return contextPath;
		}
		
		@Override
		public String getRequestURI() {
			// TODO Auto-generated method stub
			return getContextPath()+_getHttpServletRequest().getRequestURI();
		}
		
	}
}
